package com.universal.aysncCompose.controller;

/**
 * @author austin
 * @data 2022/11/7 19:38
 */

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.CompletableFuture;

@Slf4j
@RestController
@RequestMapping("/api")
public class ThenCombine {

    @SneakyThrows
    @GetMapping("/compose/thenCombine")
    public static void thenCombine() {
        CompletableFuture<Integer> cf1 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread() + " cf1 do something....");
            return 1;
        });
        CompletableFuture<Integer> cf2 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread() + " cf2 do something....");
            return 2;
        });
        /**
         * combine: 结合的意思， cf1结合cf2执行下一个任务...
         *
         */
        CompletableFuture<Integer> cf3 = cf1.thenCombine(cf2, (res1, res2) -> {
            System.out.println("cf1结果: " + res1);
            System.out.println("cf2结果: " + res2);
            System.out.println(Thread.currentThread() + " cf3 do something...");
            return res1 + res2;
        });


        System.out.println("thenCombine cf3结果 -> " + cf3.get());


    }

    @SneakyThrows
    @GetMapping("/compose/thenAcceptBoth")
    public static void thenAcceptBoth() {
        CompletableFuture<Integer> cf1 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread() + " cf1 do something....");
            return 1;
        });
        CompletableFuture<Integer> cf2 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread() + " cf2 do something....");
            return 2;
        });
        /**
         * thenAcceptBoth和thenCombine相似，区别在于thenAcceptBoth没有返回值
         *
         */
        CompletableFuture<Void> cf3 = cf1.thenAcceptBoth(cf2, (res1, res2) -> {
            System.out.println("cf1结果: " + res1);
            System.out.println("cf2结果: " + res2);
            System.out.println(Thread.currentThread() + " cf3 do something...");
        });
        System.out.println("thenAcceptBoth cf3结果 -> " + cf3.get());
    }

    @SneakyThrows
    @GetMapping("/compose/runAfterBoth")
    public static void runAfterBoth() {
        CompletableFuture<Integer> cf1 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread() + " cf1 do something....");
            return 1;
        });
        CompletableFuture<Integer> cf2 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread() + " cf2 do something....");
            return 2;
        });
        /**
         * thenAcceptBoth和thenCombine相似，区别在于thenAcceptBoth没有返回值
         *
         */
        CompletableFuture<Void> cf3 = cf1.runAfterBoth(cf2, () -> {
            System.out.println(Thread.currentThread() + " cf3 do something...");
        });
        System.out.println("runAfterBoth cf3结果 -> " + cf3.get());
    }

    public static void main(String[] args) {
        thenCombine();
        thenAcceptBoth();
        runAfterBoth();
    }
}
